/*
 * Copyright (c) 2014-2015 Luca Agostini, Alessandro Cantini, Alessandro Dignani
 *
 * This file is part of MeteoCal.
 *
 * MeteoCal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.polimi.se2.agostini_cantini_dignani.meteocal.business;

import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.Calendar;
import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.Event;
import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.Notification;
import it.polimi.se2.agostini_cantini_dignani.meteocal.entity.User;
import it.polimi.se2.agostini_cantini_dignani.meteocal.model.NotificationType;
import it.polimi.se2.agostini_cantini_dignani.meteocal.util.DateTimeUtils;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * This class manages the business logic related to notifications
 *
 * @Author Alessandro Cantini
 */
@Stateless
public class NotificationManager {

	private static final String INVITATION_START = "You have been invited by ";
	private static final String INVITATION_END = " to join the event: ";

	@EJB
	private UserManager um;

	@EJB
	private EventManager eventMgr;

	@EJB
	private EmailManager emm;

	@PersistenceContext
	private EntityManager em;

	public void sendNotification(String description, User user, Event event) {
		sendNotification(description, user, event, NotificationType.GENERIC);
	}

	public void sendInvitationNotification(User inviter, User invitee, Event event) {
		String description = INVITATION_START + inviter.getEmail() + INVITATION_END + event.getTitle();
		sendNotification(description, invitee, event, NotificationType.INVITATION);
	}

	public void removeNotification(Notification notification) {
		User user = notification.getOwner();
		if (!user.getNotifications().contains(notification)) {
			throw new IllegalArgumentException();
		}

		user.getNotifications().remove(notification);

		um.editUser(user);

		assert (!user.getNotifications().contains(notification));
	}

	public void sendChangedWeatherNotification(Event event) {
		sendWeatherNotification(event, "The weather has changed");
	}

	public void sendBadWeatherNotification(Event event) {
		sendWeatherNotification(event, "The weather is bad");
	}

	private void sendWeatherNotification(Event event, String initial) {
		for (Calendar c : event.getParticipantCalendars()) {
			String description = initial + " for the event \"" + event.getTitle() +
					"\" in date " + DateTimeUtils.format(event.getStartTime(), c.getOwner().getDateTimePattern(), c.getTimeZone());
			sendNotification(description, c.getOwner(), event, NotificationType.WEATHER);
		}
	}

	private void sendNotification(String description, User user, Event event, NotificationType type) {
		Notification notification = new Notification();
		notification.setType(type);
		notification.setDescription(description);
		notification.setOwner(user);
		user.getNotifications().add(notification);
		notification.setEvent(event);

		em.persist(notification);
		um.editUser(user);

		if (user.isReceivingEmail()) {
			emm.sendNotificationEmail(notification);
		}

		assert (user == notification.getOwner());
	}
}
